package com.jzo2o.health.service.impl;

import cn.hutool.core.bean.BeanUtil;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.api.foundations.dto.request.OrdersPayReqDTO;

import com.jzo2o.api.orders.dto.request.OrderCancelReqDTO;
import com.jzo2o.api.trade.NativePayApi;
import com.jzo2o.api.trade.TradingApi;
import com.jzo2o.api.trade.dto.request.NativePayReqDTO;
import com.jzo2o.api.trade.dto.response.NativePayResDTO;
import com.jzo2o.api.trade.dto.response.TradingResDTO;
import com.jzo2o.api.trade.enums.PayChannelEnum;
import com.jzo2o.api.trade.enums.TradingStateEnum;
import com.jzo2o.common.expcetions.CommonException;
import com.jzo2o.common.model.PageResult;
import com.jzo2o.common.model.msg.TradeStatusMsg;
import com.jzo2o.common.utils.BeanUtils;
import com.jzo2o.common.utils.ObjectUtils;
import com.jzo2o.health.enums.OrderPayStatusEnum;
import com.jzo2o.health.mapper.OrdersMapper;
import com.jzo2o.health.mapper.ReservationSettingMapper;
import com.jzo2o.health.model.domain.*;
import com.jzo2o.health.model.dto.StatusCount;

import com.jzo2o.health.model.dto.request.OrdersPageQueryReqDTO;
import com.jzo2o.health.model.dto.request.PlaceOrderReqDTO;
import com.jzo2o.health.model.dto.response.*;
import com.jzo2o.health.properties.TradeProperties;
import com.jzo2o.health.service.*;
import com.mysql.cj.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.jzo2o.common.constants.ErrorInfo.Code.TRADE_FAILED;

/**
 * @author DarkClown
 * @date 2024-08-27 16:58
 * @project_name jzo2o-health
 * @parem
 **/
@Service
public class IOrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements IOrdersService {
    @Autowired
    ISetmealService setmealService;

    @Autowired
    IOrdersService ordersService;

    @Autowired
    IMemberService memberService;

    @Autowired
    IOrdersCancelledService ordersCancelledService;

    @Autowired
    ReservationSettingMapper reservationSettingMapper;

    @Override
    public PlaceOrderResDTO place(PlaceOrderReqDTO placeOrderReqDTO, Long id) {
        Orders orders = new Orders();
        orders.setOrderStatus(0);
        orders.setPayStatus(0);
        Setmeal setmeal = setmealService.findById(placeOrderReqDTO.getSetmealId());

        if (setmeal == null){
            throw new RuntimeException("套餐不存在");
        }

        orders.setSetmealId(placeOrderReqDTO.getSetmealId());
        //获取套餐名称
        orders.setSetmealName(setmeal.getName());
        orders.setSetmealSex(setmeal.getSex());
        orders.setSetmealAge(setmeal.getAge());
        orders.setSetmealImg(setmeal.getImg());
        orders.setSetmealRemark(setmeal.getRemark());
        String s = Float.toString(setmeal.getPrice());
        BigDecimal bigDecimal = new BigDecimal(s);
        orders.setSetmealPrice(bigDecimal);

        orders.setReservationDate(placeOrderReqDTO.getReservationDate());
        orders.setCheckupPersonName(placeOrderReqDTO.getCheckupPersonName());
        orders.setCheckupPersonPhone(placeOrderReqDTO.getCheckupPersonPhone());
        orders.setCheckupPersonIdcard(placeOrderReqDTO.getCheckupPersonIdcard());
        orders.setCheckupPersonSex(placeOrderReqDTO.getCheckupPersonSex());

        orders.setMemberId(id);

        Member member = memberService.getById(id);
        if (member == null){
            throw new RuntimeException("用户不存在");
        }
        orders.setMemberPhone(member.getPhone());
        //支付时间为当前时间

        orders.setCreateTime(LocalDateTime.now());


        boolean save = ordersService.save(orders);

        //将预约数量加1
        reservationSettingMapper.addReservations(placeOrderReqDTO.getReservationDate());

        if (!save){
            throw new RuntimeException("下单失败");
        }
        return new PlaceOrderResDTO(orders.getId());

    }

    @Override
    @Transactional
    public OrderCancelReqDTO cancel(OrderCancelReqDTO orderCancelReqDTO, Long id) {
        //根据订单Id查询订单信息
        Orders orders = ordersService.getById(orderCancelReqDTO.getId());
        if (orders == null){
            throw new RuntimeException("订单不存在");
        }
        orders.setOrderStatus(400);

        orders.getReservationDate();

        reservationSettingMapper.updateReservationSetting(orders.getReservationDate());


        boolean b = ordersService.updateById(orders);
        if (!b){
            throw new RuntimeException("取消失败");
        }

        OrdersCancelled ordersCancelled = new OrdersCancelled();
        //通过id获取用户信息
        Member member = memberService.getById(id);

        ordersCancelled.setCancellerId(id);
        ordersCancelled.setCancellerName(member.getNickname());
        ordersCancelled.setCancellerType(1);
        ordersCancelled.setCancelReason(orderCancelReqDTO.getCancelReason());
        ordersCancelled.setCancelTime(LocalDateTime.now());
        ordersCancelled.setCreateTime(orders.getCreateTime());
        //保存
        boolean save = ordersCancelledService.save(ordersCancelled);
        if (!save){
            throw new RuntimeException("取消失败");
        }
        return orderCancelReqDTO;

    }

    @Autowired
    private IOrdersRefundService ordersRefundService;

    @Override
    public OrderCancelReqDTO refund(OrderCancelReqDTO orderCancelReqDTO) {
        //根据订单Id查询订单信息
        Orders orders = ordersService.getById(orderCancelReqDTO.getId());

        if (orders == null){
            throw new RuntimeException("订单不存在");
        }

        OrdersRefund ordersRefund = new OrdersRefund();

        ordersRefund.setTradingOrderNo(orders.getTradingOrderNo());

        // todo 没有支付金额,用的套餐价格
        ordersRefund.setRealPayAmount(orders.getSetmealPrice());

        ordersRefund.setCreateTime(LocalDateTime.now());
        //更改Orders表中的状态
        boolean save = ordersRefundService.save(ordersRefund);
        if (!save){
            throw new RuntimeException("退款失败");
        }

        return orderCancelReqDTO;

    }

    @Override
    public List<OrdersResDTO> page(Integer ordersStatus, Long sortBy) {
        //查询订单列表
        QueryWrapper<Orders> ordersQueryWrapper = new QueryWrapper<>();
        //如果订单状态不为空,根据订单状态查询
        if (BeanUtil.isNotEmpty(ordersStatus)){
            ordersQueryWrapper.lambda().eq(Orders::getOrderStatus, ordersStatus);
        }


        //根据排序字段排序
        ordersQueryWrapper.lambda().orderByDesc(Orders::getSortBy);

        List<Orders> list = ordersService.list(ordersQueryWrapper);

        return BeanUtil.copyToList(list, OrdersResDTO.class);



    }

    @Override
    public OrdersDetailResDTO getDetail(Long id) {
        Orders byId = ordersService.getById(id);
        return BeanUtil.toBean(byId, OrdersDetailResDTO.class);
    }

    @Override
    public PageResult<OrdersResDTO> pageQuery(OrdersPageQueryReqDTO ordersPageQueryReqDTO) {
        //创建分页
        Page<Orders> ordersPage = new Page<>(ordersPageQueryReqDTO.getPageNo(),ordersPageQueryReqDTO.getPageSize());

        QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
        //根据用户电话查询
        if (BeanUtil.isNotEmpty(ordersPageQueryReqDTO.getMemberPhone())&& ordersPageQueryReqDTO.getMemberPhone()!=""){
            queryWrapper.lambda().eq(Orders::getMemberPhone,ordersPageQueryReqDTO.getMemberPhone());
        }
        //根据订单状态查询
        if (BeanUtil.isNotEmpty(ordersPageQueryReqDTO.getOrderStatus())){
            queryWrapper.lambda().eq(Orders::getOrderStatus,ordersPageQueryReqDTO.getOrderStatus());
        }

        Page<Orders> page = ordersService.page(ordersPage, queryWrapper);

        List<Orders> records = page.getRecords();
        List<OrdersResDTO> ordersResDTOS = BeanUtil.copyToList(records, OrdersResDTO.class);

        PageResult<OrdersResDTO> ordersResDTOPageResult = new PageResult<>();

        ordersResDTOPageResult.setList(ordersResDTOS);
        ordersResDTOPageResult.setTotal(page.getTotal());
        ordersResDTOPageResult.setPages(page.getPages());
        return ordersResDTOPageResult;
    }

    @Autowired
    OrdersMapper ordersMapper;

    @Resource
    IOrdersCreateService owner;

    @Resource
    TradingApi tradingApi;

    @Override
    public OrdersCountResDTO countByStatus() {
        OrdersCountResDTO ordersCountResDTO = new OrdersCountResDTO();

        //支付状态
//        List<StatusCount> payCount =  ordersMapper.selectPayStatusCount();
//
//        //订单状态
//        List<StatusCount> ordersCount = new ArrayList<>();
//        // 填充列表
//        for (int i = 0; i < 5; i++) {
//            ordersCount.add(new StatusCount(0, 0));
//        }
//
//        // 更新列表中的元素
//        ordersCount.set(0, new StatusCount(0, 0));
//        ordersCount.set(1, new StatusCount(100, 0));
//        ordersCount.set(2, new StatusCount(300, 0));
//        ordersCount.set(3, new StatusCount(200, 0));
//        ordersCount.set(4, new StatusCount(400, 0));
//        // TODO: 2024/8/27 待支付数量
//        List<StatusCount> ordersCount1 =  ordersMapper.selectorderStatusCount();
//
//        for (StatusCount statusCount : ordersCount) {
//            for (StatusCount statusCount1 : ordersCount1) {
//                if (statusCount.getStatus() == statusCount1.getStatus()){
//                    statusCount.setCount(statusCount1.getCount());
//                }
//            }
//        }
//
//        //已体检
//        ordersCountResDTO.setCompletedCheckupCount(ordersCount.get(3).getCount());
//        //待体检数量
//        ordersCountResDTO.setWaitingCheckupCount(ordersCount.get(1).getCount());
//        //已取消数量
//        ordersCountResDTO.setCancelledCount(ordersCount.get(4).getCount());
//        //待支付数量
//        ordersCountResDTO.setNoPayCount(ordersCount.get(0).getCount());
//        //已关闭数量
//        ordersCountResDTO.setClosedCount(ordersCount.get(2).getCount());





        // 订单状态初始化
        List<StatusCount> ordersCount = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            ordersCount.add(new StatusCount(i * 100, 0));  // 初始化时直接设定状态
        }

// 从数据库中获取状态计数
        List<StatusCount> ordersCount1 = ordersMapper.selectorderStatusCount();
        if (ordersCount1 == null) {
            ordersCount1 = new ArrayList<>();
        }

// 使用Map优化状态匹配
        Map<Integer, Integer> statusCountMap = new HashMap<>();
        for (StatusCount statusCount1 : ordersCount1) {
            if (statusCount1 != null) {
                statusCountMap.put(statusCount1.getStatus(), statusCount1.getCount());
            }
        }

// 更新 ordersCount 列表中的元素
        for (StatusCount statusCount : ordersCount) {
            if (statusCount != null) {
                Integer count = statusCountMap.get(statusCount.getStatus());
                if (count != null) {
                    statusCount.setCount(count);
                }
            }
        }

// 确保 ordersCountResDTO 被初始化
        if (ordersCountResDTO != null) {
            ordersCountResDTO.setCompletedCheckupCount(ordersCount.get(3).getCount()); // 已体检
            ordersCountResDTO.setWaitingCheckupCount(ordersCount.get(1).getCount());   // 待体检
            ordersCountResDTO.setCancelledCount(ordersCount.get(4).getCount());        // 已取消
            ordersCountResDTO.setNoPayCount(ordersCount.get(0).getCount());            // 待支付
            ordersCountResDTO.setClosedCount(ordersCount.get(2).getCount());           // 已关闭
        }

        return ordersCountResDTO;
    }




    public OrdersPayResDTO pay(Long id,PayChannelEnum tradingChannel) {
        Orders orders = baseMapper.selectById(id);

        if (ObjectUtil.isNull(orders)) {
            throw new CommonException(TRADE_FAILED, "订单不存在");
        }
        //订单的支付状态为成功直接返回
        if (OrderPayStatusEnum.PAY_SUCCESS.getStatus() == orders.getPayStatus() && ObjectUtil.isNotNull(orders.getTradingOrderNo())) {
            OrdersPayResDTO ordersPayResDTO = new OrdersPayResDTO();

            BeanUtil.copyProperties(orders, ordersPayResDTO);

            ordersPayResDTO.setProductOrderNo(orders.getId());
            return ordersPayResDTO;

        } else {
            NativePayResDTO nativePayResDTO = generaQrCode(orders, tradingChannel);
            OrdersPayResDTO ordersPayResDTO = BeanUtil.toBean(nativePayResDTO, OrdersPayResDTO.class);
            return ordersPayResDTO;
        }

    }

    @Override
    public OrdersPayResDTO getPayResultFromTradServer(Long id) {
        //查询订单表
        Orders orders = baseMapper.selectById(id);
        if (ObjectUtil.isNull(orders)){
            throw new CommonException(TRADE_FAILED,"订单不存在");
        }
        //支付结果
        Integer payStatus = orders.getPayStatus();
        if (OrderPayStatusEnum.NO_PAY.getStatus()==payStatus&&ObjectUtil.isNotNull(orders.getTradingOrderNo())){
            TradingResDTO tradingResDTO = tradingApi.findTradResultByTradingOrderNo(orders.getTradingOrderNo());

            //如果支付成功这里更新订单状态
            if (ObjectUtil.isNotNull(tradingResDTO)&&ObjectUtil.equals(tradingResDTO.getTradingState(), TradingStateEnum.YJS)){
                TradeStatusMsg msg = TradeStatusMsg.builder()
                        .productOrderNo(orders.getId())
                        .tradingChannel(tradingResDTO.getTradingChannel())
                        .statusCode(TradingStateEnum.YJS.getCode())
                        .tradingOrderNo(tradingResDTO.getTradingOrderNo())
                        .transactionId(tradingResDTO.getTransactionId())
                        .build();
                owner.paySuccess(msg);

                OrdersPayResDTO ordersPayResDTO = BeanUtils.toBean(tradingResDTO, OrdersPayResDTO.class);

                ordersPayResDTO.setPayStatus(OrderPayStatusEnum.PAY_SUCCESS.getStatus());
                return ordersPayResDTO;

            }


        }
        OrdersPayResDTO ordersPayResDTO = new OrdersPayResDTO();
        ordersPayResDTO.setPayStatus(payStatus);
        ordersPayResDTO.setProductOrderNo(orders.getId());
        ordersPayResDTO.setTradingOrderNo(orders.getTradingOrderNo());
        ordersPayResDTO.setTradingChannel(orders.getTradingChannel());
        return ordersPayResDTO;

    }

    private NativePayResDTO generaQrCode(Orders orders, PayChannelEnum tradingChannel) {
        Long enterpriseId = ObjectUtil.equals(PayChannelEnum.ALI_PAY, tradingChannel) ? tradeProperties.getAliEnterpriseId() : tradeProperties.getWechatEnterpriseId();

        //构建支付请求参数
        NativePayReqDTO nativePayReqDTO = new NativePayReqDTO();
        //设置商户号
        nativePayReqDTO.setEnterpriseId(enterpriseId);
        //设置业务系统标识
        nativePayReqDTO.setProductAppId("jzo2o.orders");
        //设置家政订单号
        nativePayReqDTO.setProductOrderNo(orders.getId());
        //支付渠道
        nativePayReqDTO.setTradingChannel(tradingChannel);
        //支付金额
        nativePayReqDTO.setTradingAmount(new BigDecimal(0.01));

        //备注信息
        nativePayReqDTO.setMemo(orders.getSetmealName());
        //判断是否切换支付渠道
        if (ObjectUtil.isNotEmpty(orders.getTradingChannel()) && ObjectUtil.notEqual(orders.getTradingChannel(), tradingChannel.toString())) {
            nativePayReqDTO.setChangeChannel(true);
        }
        //生成支付二维码
        NativePayResDTO downLineTrading = nativePayApi.createDownLineTrading(nativePayReqDTO);
        if (ObjectUtils.isNotNull(downLineTrading)) {
            //将二维码更新到交易订单中
            boolean update = lambdaUpdate()
                    .eq(Orders::getId, downLineTrading.getProductOrderNo())
                    .set(Orders::getTradingOrderNo, downLineTrading.getTradingOrderNo())
                    .set(Orders::getTradingChannel, downLineTrading.getTradingChannel())
                    .update();
            if (!update) {
                throw new CommonException("订单:" + orders.getId() + "请求支付更新交易单号失败");
            }

        }

        return downLineTrading;
    }

    @Autowired
    TradeProperties tradeProperties;

    @Resource
    NativePayApi nativePayApi;




//    @Override
//    public OrdersPayResDTO pay(Long id, PayChannelEnum tradingChannel) {
//
//        Orders orders = baseMapper.selectById(id);
//
//        if (ObjectUtil.isNull(orders)) {
//            throw new CommonException(TRADE_FAILED, "订单不存在");
//        }
//        //订单的支付状态为成功直接返回
//        if (OrderPayStatusEnum.PAY_SUCCESS.getStatus() == orders.getPayStatus() && ObjectUtil.isNotNull(orders.getTradingOrderNo())) {
//            OrdersPayResDTO ordersPayResDTO = new OrdersPayResDTO();
//
//            BeanUtil.copyProperties(orders, ordersPayResDTO);
//
//            ordersPayResDTO.setProductOrderNo(orders.getId());
//            return ordersPayResDTO;
//
//        } else {
//            NativePayResDTO nativePayResDTO = generaQrCode(orders, ordersPayReqDTO.getTradingChannel());
//            OrdersPayResDTO ordersPayResDTO = BeanUtil.toBean(nativePayResDTO, OrdersPayResDTO.class);
//            return ordersPayResDTO;
//        }
//
//    }
//
//
//    private NativePayResDTO generaQrCode(Orders orders, PayChannelEnum tradingChannel) {
//        Long enterpriseId = ObjectUtil.equals(PayChannelEnum.ALI_PAY, tradingChannel) ? tradeProperties.getAliEnterpriseId() : tradeProperties.getWechatEnterpriseId();
//
//        //构建支付请求参数
//        NativePayReqDTO nativePayReqDTO = new NativePayReqDTO();
//        //设置商户号
//        nativePayReqDTO.setEnterpriseId(enterpriseId);
//        //设置业务系统标识
//        nativePayReqDTO.setProductAppId("jzo2o.orders");
//        //设置家政订单号
//        nativePayReqDTO.setProductOrderNo(orders.getId());
//        //支付渠道
//        nativePayReqDTO.setTradingChannel(tradingChannel);
//        //支付金额
//        nativePayReqDTO.setTradingAmount(orders.getRealPayAmount());
//
//        //备注信息
//        nativePayReqDTO.setMemo(orders.getServeItemName());
//        //判断是否切换支付渠道
//        if (ObjectUtil.isNotEmpty(orders.getTradingChannel()) && ObjectUtil.notEqual(orders.getTradingChannel(), tradingChannel.toString())) {
//            nativePayReqDTO.setChangeChannel(true);
//        }
//        //生成支付二维码
//        NativePayResDTO downLineTrading = nativePayApi.createDownLineTrading(nativePayReqDTO);
//        if (ObjectUtil.isNotNull(downLineTrading)) {
//            log.info("订单:{}请求支付,生成二维码:{}", orders.getId(), downLineTrading.toString());
//
//            //将二维码更新到交易订单中
//            boolean update = lambdaUpdate()
//                    .eq(Orders::getId, downLineTrading.getProductOrderNo())
//                    .set(Orders::getTradingOrderNo, downLineTrading.getTradingOrderNo())
//                    .set(Orders::getTradingChannel, downLineTrading.getTradingChannel())
//                    .update();
//            if (!update) {
//                throw new CommonException("订单:" + orders.getId() + "请求支付更新交易单号失败");
//            }
//
//        }
//
//        return downLineTrading;
//    }

}
